#include <utils/FileIO.h>

namespace myamg {
    bool writeFeaturesToCSV(const std::vector<std::vector<std::pair<std::string, std::string> > > &features,
                            const std::string &filename) {
        if (features.empty()) {
            std::cerr << "writeFeaturesToCSV: No features to write." << std::endl;
            return false;
        }

        std::ofstream outFile(filename);
        if (!outFile.is_open()) {
            std::cerr << "writeFeaturesToCSV: Cannot open file " << filename << std::endl;
            return false;
        }

        // Collect union of all keys from all maps, preserving order of first appearance
        std::vector<std::string> allKeys;

        for (const auto &featureMap: features) {
            for (const auto &pair: featureMap) {
                // Add key if not already present
                if (std::find(allKeys.begin(), allKeys.end(), pair.first) == allKeys.end()) {
                    allKeys.push_back(pair.first);
                }
            }
        }

        // Write header
        for (size_t i = 0; i < allKeys.size(); ++i) {
            outFile << allKeys[i];
            if (i < allKeys.size() - 1) {
                outFile << ",";
            }
        }
        outFile << "\n";

        // Write data rows
        for (const auto &featureMap: features) {
            // Build a map for quick lookup
            std::map<std::string, std::string> lookupMap;
            for (const auto &pair: featureMap) {
                lookupMap[pair.first] = pair.second;
            }

            for (size_t i = 0; i < allKeys.size(); ++i) {
                auto it = lookupMap.find(allKeys[i]);
                if (it != lookupMap.end()) {
                    // Escape values containing commas, quotes, or newlines
                    std::string value = it->second;
                    if (value.find(',') != std::string::npos ||
                        value.find('"') != std::string::npos ||
                        value.find('\n') != std::string::npos) {
                        // Replace quotes with double quotes and wrap in quotes
                        size_t pos = 0;
                        while ((pos = value.find('"', pos)) != std::string::npos) {
                            value.insert(pos, "\"");
                            pos += 2;
                        }
                        outFile << "\"" << value << "\"";
                    } else {
                        outFile << value;
                    }
                }
                // If key doesn't exist in this map, leave empty (already handled by not writing anything)
                if (i < allKeys.size() - 1) {
                    outFile << ",";
                }
            }
            outFile << "\n";
        }

        outFile.close();
        return true;
    }

}
